﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ESP
{
    public class ESP_Partition
    {
        /*
         *有关FindESP命令，请参阅 https://gitee.com/AZPEP_BiliBili/findesp-desktop/blob/master/docs/FindESP%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E-v2.0-%E7%AE%80%E4%BD%93(%E4%B8%AD%E6%96%87).md
         */
        /// <summary>
        /// 挂载所有ESP分区
        /// </summary>
        public static bool MountAllESP()
        {
            return runFindESP("-mount");
            
        }

        /// <summary>
        /// 卸载所有ESP分区
        /// <param name="NotShowError">是否抛出异常</param>
        /// </summary>
        public static bool UnmountAllESP(
            bool NotShowError = false
            )
        {
            try
            {
                return runFindESP("-unmount",NotShowError);
            }
            catch
            {
                //tss...
                return true;
            }

            
            
        }

        /// <summary>
        /// 对指定盘符所在磁盘的所有esp分区挂载, 已挂载的不会重复挂载, 如果不成功或没有esp分区则报错
        /// </summary>
        /// <param name="letter">盘符，应为"C"而不是"C:\"</param>
        /// <returns></returns>
        public static bool MountESP2Letter(string letter)
        {
            return runFindESP($"-mount:{letter}");
        }

        /// <summary>
        /// 对指定盘符所在磁盘的所有esp分区卸载, 已卸载的不会重复卸载,如果不成功或没有esp分区则报错
        /// </summary>
        /// <param name="letter">盘符，应为"C"而不是"C:\"</param>
        /// <param name="NotShowError">是否抛出异常</param>
        /// <returns></returns>
        public static bool UnmountESPfromLetter(
            string letter, 
            bool NotShowError = false
            )
        {
            return runFindESP($"-unmount:{letter}",NotShowError);
        }

        /// <summary>
        /// 加载指定硬盘上的所有ESP分区
        /// </summary>
        /// <param name="diskNumber" >硬盘号</param>
        /// <returns></returns>
        public static bool MountAllESPfromDisk(int diskNumber)
        {
            return runFindESP($"-mount:{diskNumber}");
        }

        /// <summary>
        /// 卸载指定硬盘上的所有ESP分区
        /// </summary>
        /// <param name="diskNumber" >硬盘号</param>
        /// <param name="NotShowError">是否抛出异常</param>
        /// <returns></returns>
        public static bool UnmountAllESPfromDisk(
            int diskNumber,
            bool NotShowError = false
            )
        {
            return runFindESP($"-unmount:{diskNumber}", NotShowError);
        }

        /// <summary>
        /// 运行FindESP.exe，执行命令
        /// </summary>
        /// <param name="parameter">运行参数</param>
        /// <param name="NotShowError">是否抛出异常</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private static bool runFindESP(
            string parameter,
            bool NotShowError=false
         )
        {
            string FindESP_Path = Environment.GetEnvironmentVariable("TEMP") + @"\FindESP.exe";
            FileStream FindESPFileHandle = new FileStream(FindESP_Path, FileMode.Create);
            Byte[] FindESPdata = global::ESP.Resource.FindESP;
            FindESPFileHandle.Write(FindESPdata, 0, FindESPdata.Length);
            FindESPFileHandle.Close();

            Process p = new Process();
            //设置要启动的应用程序
            p.StartInfo.FileName = FindESP_Path;
            //是否使用操作系统shell启动
            p.StartInfo.UseShellExecute = false;
            // 接受来自调用程序的输入信息
            p.StartInfo.RedirectStandardInput = true;
            //输出信息
            p.StartInfo.RedirectStandardOutput = true;
            // 输出错误
            p.StartInfo.RedirectStandardError = true;
            //不显示程序窗口
            p.StartInfo.CreateNoWindow = true;

            p.StartInfo.Arguments = parameter;

            p.Start();

            StreamReader reader = p.StandardOutput;
            string output = reader.ReadToEnd();

            p.WaitForExit();
            

            if(p.ExitCode != 0)
            {
                p.Close();
                Debug.WriteLine(output);

                if (!NotShowError)
                {
                    throw new Exception(output);
                }

                return false;
            }
            else
            {
                p.Close();
                return true;
            }
        }
    }
}
